package com.itheima;

import com.alibaba.fastjson.JSON;
import com.itheima.pojo.User;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.Avg;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 高亮搜索
 * @作者 itcast
 * @创建日期 2020/11/3 9:00
 **/
public class EsDemo04 {
    RestHighLevelClient client;
    @Test
    public void aggs() throws IOException {
        // 1. 创建search请求
        SearchRequest request = new SearchRequest("user");
        // 构建搜索条件
        SearchSourceBuilder builder = new SearchSourceBuilder();
        // 构建聚合条件
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders
                .terms("terms_by_gender")
                .field("gender")
                .subAggregation(AggregationBuilders.avg("avg_by_age").field("age"));// 构建分桶聚合类型条件
        builder.aggregation(termsAggregationBuilder);
        request.source(builder);
        // 2. 执行search请求
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        // 获取全部聚合结果
        Aggregations aggregations = searchResponse.getAggregations();
        // 获取不同类型的聚合结果，一定要用对应的聚合类型接口来介绍
        Terms terms_by_gender = aggregations.get("terms_by_gender");
        // 在分桶结果中 找到具体的分桶信息 buckets
        List<? extends Terms.Bucket> buckets = terms_by_gender.getBuckets();
        for (Terms.Bucket bucket : buckets) {
            System.out.println("该分桶的key==>" + bucket.getKeyAsString());
            System.out.println("该分桶下的数据==>" + bucket.getDocCount());
            // 获取分桶下所有子聚合结果
            Aggregations subAggs = bucket.getAggregations();
            Avg avgResult = subAggs.get("avg_by_age");
            System.out.println("该分桶下平均年龄==>" + avgResult.getValue());
        }
    }
    @Test
    public void  highlight() throws IOException {
        // 1. 创建search请求
        SearchRequest request = new SearchRequest("user");
        // 构建搜索条件
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchQuery("note","唱歌javaee"));

        // 高亮条件
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("note"); // 高亮的字段
        highlightBuilder.preTags("<span>"); // 前置标签
        highlightBuilder.postTags("</span>"); // 后置标签
        builder.highlighter(highlightBuilder);
        request.source(builder);
        // 2. 执行search请求
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits(); // 获取总结果
        System.out.println("查询结果记录数: " + hits.getTotalHits().value);
        SearchHit[] docList = hits.getHits(); // 文档列表
        for (SearchHit searchHit : docList) {
            String userJson = searchHit.getSourceAsString();
            User user = JSON.parseObject(userJson, User.class);
            // 处理高亮结果   获取高亮字段中高亮的处理结果，使用高亮处理结果替换 user中的note字段
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            highlightFields.forEach((key,val)->{
                if("note".equals(key)){
                    // 所有高亮处理片段数组
                    Text[] fragments = val.getFragments();
                    StringBuilder  sb = new StringBuilder();
                    // 将高亮片段结果 拼接到一起 得到完整的高亮处理结果
                    for (Text fragment : fragments) {
                        sb.append(fragment);
                    }
                    // 替换掉之前user中的note
                    user.setNote(sb.toString());
                }
            });
            System.out.println(user);
        }
    }
    @Before
    public void init(){
        // 构建ES的客户端
        client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("localhost",9200,"http")
                )
        );
    }
    @After
    public void close(){
        try {
            client.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
